package be.groept.ace.cursusplanning.model.containers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import be.groept.ace.cursusplanning.model.AangebodenCursus;
import be.groept.ace.cursusplanning.model.Cursist;
import be.groept.ace.cursusplanning.model.Cursus;
import be.groept.ace.cursusplanning.model.Inschrijving;
import be.groept.ace.cursusplanning.utils.observer.EventArgs;
import be.groept.ace.cursusplanning.utils.observer.PropertyChanged;
import be.groept.ace.cursusplanning.utils.observer.Subject;
import be.groept.ace.cursusplanning.utils.observer.Subscriber;

public class Cursussen implements Container<Cursus, Integer> {
	
	private Map<Integer, Cursus> cursussen;
	
	private Subject<AangebodenCursus[]> alleAangebodenCursussenNogNietIngeschrevenVoorCursistSubject;
	
	public Cursussen() {
		cursussen = new HashMap<Integer, Cursus>();
		alleAangebodenCursussenNogNietIngeschrevenVoorCursistSubject = new PropertyChanged<AangebodenCursus[]>();
	}

	@Override
	public void add(Cursus cursus) throws IllegalArgumentException{
		if(cursus == null) throw new IllegalArgumentException("null kan niet toegevoegd worden.");
		if(cursussen.containsKey(cursus.getCursusCode())) throw new IllegalArgumentException("De cursus " + cursus.getCursusNaam() + " bestaat al in deze container.");
		cursussen.put(new Integer(cursus.getCursusCode()), cursus);
	}

	@Override
	public Cursus get(Integer key) throws IllegalArgumentException{
		if(key == null) throw new IllegalArgumentException("key mag niet null zijn");
		if(!cursussen.containsKey(key)) throw new IllegalArgumentException("De key bestaat niet in deze container.");
		return cursussen.get(key);
	}

	@Override
	public List<Cursus> getAll() {
		List<Cursus> cursusLijst = new ArrayList<Cursus>();
		for(Iterator<Integer> i = cursussen.keySet().iterator(); i.hasNext();) {
			cursusLijst.add(cursussen.get(i.next()));
		}
		return cursusLijst;
	}

	@Override
	public void remove(Integer key) {
		if(key == null) throw new IllegalArgumentException("key mag niet null zijn");
		if(!cursussen.containsKey(key)) throw new IllegalArgumentException("De key bestaat niet in deze container.");
		cursussen.remove(key);
	}

	@Override
	public Iterator<Cursus> iterator() {
		return cursussen.values().iterator();
	}
	
	public AangebodenCursus[] getAlleAangebodenCursussenNogNietIngeschrevenVoorCursist(Cursist cursist) {
		
		List<AangebodenCursus> aangebodenCursussen = getAllAangebodenCursussenMetStrategy(cursist);
		
		for(Inschrijving inschrijving: cursist.getInschrijvingen()) {
			if(aangebodenCursussen.contains(inschrijving.getAangebodenCursus())) {
				aangebodenCursussen.remove(inschrijving.getAangebodenCursus());
			}
		}
		return aangebodenCursussen.toArray(new AangebodenCursus[aangebodenCursussen.size()]);
	}
	
	public List<AangebodenCursus> getAllAangebodenCursussen() {
		List<AangebodenCursus> aangebodenCursussen = new ArrayList<AangebodenCursus>();
		for(Cursus cursus: getAll()) {
			aangebodenCursussen.addAll(aangebodenCursussen.size(), cursus.getAangebodenCursussen());
		}
		return aangebodenCursussen;
	}
	
	public List<AangebodenCursus> getAllAangebodenCursussenMetStrategy(Cursist cursist) {
		List<AangebodenCursus> aangebodenCursussen = new ArrayList<AangebodenCursus>();
		for(AangebodenCursus aangebodenCursus: getAllAangebodenCursussen()) {
			if(aangebodenCursus.magDeelnemenAanAangebodenCursus(cursist)){
				aangebodenCursussen.add(aangebodenCursus);
			}
		}
		return aangebodenCursussen;
	}
	
	public void addAlleAangebodenCursussenNogNietIngeschrevenVoorCursistSubscriber(Subscriber<AangebodenCursus[]> subscriber) {
		alleAangebodenCursussenNogNietIngeschrevenVoorCursistSubject.addSubscriber(subscriber);
	}
	
	public void fireAlleAangebodenCursussenNogNietIngeschrevenVoorCursist(Cursist cursist) {
		alleAangebodenCursussenNogNietIngeschrevenVoorCursistSubject.notifySubscribers(new EventArgs<AangebodenCursus[]>(getAlleAangebodenCursussenNogNietIngeschrevenVoorCursist(cursist)));
	}

}
